import 'package:dio/dio.dart';
import 'package:fast_cached_network_image/fast_cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_image_picker/util/file_preview_helper.dart';
import 'package:flutter_image_picker/util/http_file_util.dart';
import 'package:flutter_image_picker/util/permission_util.dart';
import 'package:flutter_image_picker/util/toast_util.dart';
import 'package:flutter_image_picker/util/web_file_picker_util.dart';
import 'package:image_picker/image_picker.dart';

/// 上传页面
class UploadPage extends StatefulWidget {
  const UploadPage({super.key});

  @override
  State<StatefulWidget> createState() {
    return UploadPageState();
  }
}

/// 上传文件类型
enum UploadType {
  // 图片
  image,
  // 视频
  video
}

/// 选取类型
enum TakeType {
  // 从相机拍照后选择
  camera,
  // 从图库中选择
  gallery
}

class UploadPageState extends State<UploadPage> {
  /// 上传的文件Url
  String _uploadFileUrl = "";

  /// Web端的文件选择和上传
  void _takeAndUploadByWeb(UploadType uploadType) async {
    // 选择成功，则发起上传请求
    void onTakeCallback(bytes, fileName) {
      _uploadBytesFile(bytes, fileName, (url) {
        setState(() {
          _uploadFileUrl = url;
          ToastUtil.toast("上传成功");
        });
      }, () {
        ToastUtil.toast("上传失败，请重试");
      });
    }

    // 选择失败
    onTakeFailCallback() {
      ToastUtil.toast("选择失败，请重试");
    }

    if (uploadType == UploadType.image) {
      WebFilePickerUtil.takeImage(onTakeCallback, onTakeFailCallback);
    } else if (uploadType == UploadType.video) {
      WebFilePickerUtil.takeVideo(onTakeCallback, onTakeFailCallback);
    } else {
      ToastUtil.toast("不支持上传该类型的文件");
    }
  }

  /// 上传图片或视频
  void _takeAndUpload(UploadType uploadType, TakeType type) async {
    // 申请相机、存储等权限
    var isGrantedCamera = await PermissionUtil.requestCameraPermission();
    var isGrantedStorage = await PermissionUtil.requestStoragePermission();

    if (!isGrantedCamera) {
      ToastUtil.toast("未允许相机权限");
      return;
    }
    if (!isGrantedStorage) {
      ToastUtil.toast("未允许存储读写权限");
      return;
    }

    ImageSource imageSource;
    // 打开相机
    if (type == TakeType.camera) {
      imageSource = ImageSource.camera;
    } else {
      // 打开图库
      imageSource = ImageSource.gallery;
    }

    XFile? pickedFile;
    if (uploadType == UploadType.image) {
      pickedFile = await ImagePicker().pickImage(source: imageSource);
    } else if (uploadType == UploadType.video) {
      pickedFile = await ImagePicker().pickVideo(source: imageSource);
    } else {
      ToastUtil.toast("不支持上传该类型的文件");
      return;
    }
    if (pickedFile != null) {
      // 选择的文件
      String path = pickedFile.path;
      // 选择的文件名
      var fileName = path.substring(path.lastIndexOf("/") + 1, path.length);
      // 文件转字节数组
      var bytes = await pickedFile.readAsBytes();
      // 发起上传文件请求
      _uploadBytesFile(bytes, fileName, (url) {
        // 上传成功
        setState(() {
          _uploadFileUrl = url;
          ToastUtil.toast("上传成功");
        });
      }, () {
        // 上传失败
        ToastUtil.toast("上传失败，请重试");
      });
    }
  }

  /// 发起上传文件请求
  void _uploadBytesFile(
    Uint8List bytes,
    String fileName,
    Function onSuccess,
    Function? onFail,
  ) {
    MultipartFile multipartFile = MultipartFile.fromBytes(
      bytes,
      filename: fileName,
    );
    FormData data = FormData.fromMap({
      // file是上传的参数名，要与服务端接口定义对应
      "file": multipartFile,
    });
    HttpFileUtil.fileUpload(
      (String url) {
        // 上传成功后，返回的文件地址
        onSuccess(url);
      },
      //上传的文件数据
      formData: data,
      errorCallBack: (errorMsg) {
        onFail?.call("上传失败：$errorMsg");
      },
    );
  }

  /// 从底部弹出CupertinoActionSheet
  void _handleTapUpload(UploadType uploadType) {
    // Web端
    if (kIsWeb) {
      _takeAndUploadByWeb(uploadType);
    } else {
      // 移动端
      showCupertinoModalPopup(
        context: context,
        builder: (BuildContext context) => _buildActionSheet(uploadType),
      ).then((value) {});
    }
  }

  /// 构建底部弹出菜单actionSheet
  Widget _buildActionSheet(UploadType uploadType) {
    return CupertinoActionSheet(
      title: const Text(
        '请选择',
      ),
      actions: <Widget>[
        CupertinoActionSheetAction(
          child: const Text(
            '相机',
            style: TextStyle(
              fontSize: 14.0,
            ),
          ),
          onPressed: () {
            // 打开相机拍照
            _takeAndUpload(uploadType, TakeType.camera);
            // 关闭菜单
            Navigator.of(context).pop();
          },
        ),
        CupertinoActionSheetAction(
          child: const Text(
            '相册',
            style: TextStyle(
              fontSize: 14.0,
            ),
          ),
          onPressed: () {
            // 打开相册，选取照片
            _takeAndUpload(uploadType, TakeType.gallery);
            // 关闭菜单
            Navigator.of(context).pop();
          },
        )
      ],
      cancelButton: CupertinoActionSheetAction(
        child: const Text(
          '取消',
          style: TextStyle(
            fontSize: 13.0,
            color: Color(0xFF666666),
          ),
        ),
        onPressed: () {
          // 关闭菜单
          Navigator.of(context).pop();
        },
      ),
    );
  }

  /// 构建上传按钮
  Widget _buildUploadBtn(UploadType uploadType, String text) {
    return GestureDetector(
      onTap: () {
        // 上传图片或视频
        _handleTapUpload(uploadType);
      },
      child: Container(
        height: 150.0,
        width: 150.0,
        margin: const EdgeInsets.only(right: 5.0),
        color: const Color(0xFFC7C4BF),
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Icon(
                Icons.add,
                size: 40.0,
                color: Colors.white,
              ),
              Container(
                margin: const EdgeInsets.only(top: 5.0),
                child: Text(
                  text,
                  style: const TextStyle(color: Colors.white, fontSize: 14.0),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  /// 构建文件预览控件
  Widget _buildFilePreviewWidget(String uploadFileUrl) {
    if (_uploadFileUrl.isEmpty) {
      return Container();
    } else {
      if (FilePreviewHelper.isImageFile(uploadFileUrl)) {
        // 图片文件
        return FastCachedImage(
          url: _uploadFileUrl,
          loadingBuilder: (context, progress) => const Center(
            child: CircularProgressIndicator(),
          ),
          errorBuilder: (context, exception, stacktrace) => const Center(
            child: Icon(Icons.error),
          ),
        );
      } else {
        // 视频文件
        return Container(
          color: Colors.grey,
          child: const Center(
            child: Text(
              "视频",
              style: TextStyle(
                color: Colors.white,
                fontSize: 15.0,
              ),
            ),
          ),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
            onPressed: () {
              Navigator.pop(context, null);
            },
            icon: const Icon(Icons.arrow_back)),
        title: const Text("上传"),
      ),
      body: Column(
        children: [
          Expanded(
            flex: 1,
            child: GestureDetector(
              onTap: () {
                FilePreviewHelper.goPreviewPage(context, _uploadFileUrl);
              },
              child: _buildFilePreviewWidget(_uploadFileUrl),
            ),
          ),
          Container(
            margin: const EdgeInsets.all(5.0),
            child: Row(
              children: [
                _buildUploadBtn(UploadType.image, "上传图片"),
                _buildUploadBtn(UploadType.video, "上传视频"),
              ],
            ),
          )
        ],
      ),
    );
  }
}
